package com.itheima.service.impl;

import com.itheima.common.utils.DateUtils;
import com.itheima.mapper.MemberMapper;
import com.itheima.mapper.OrderMapper;
import com.itheima.mapper.SetmealMapper;
import com.itheima.pojo.HotSetmeal;
import com.itheima.pojo.Order;
import com.itheima.pojo.SetmealCount;
import com.itheima.service.ReportService;
import com.itheima.vo.BusinessReportDataVO;
import com.itheima.vo.MemberReportVO;
import com.itheima.vo.SetmealReportVO;
import com.sun.org.apache.bcel.internal.generic.NEW;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;

import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Collections;

import java.util.Date;
import java.util.List;

@Service
public class ReportServiceImpl implements ReportService {

    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    @Autowired
    private OrderMapper orderMapper;
    /**
     * 获取会员统计数据
     * @return
     */
    @Override
    public MemberReportVO getMemberReport() {
        LocalDate now = LocalDate.now(); // 当前日期
        YearMonth yearMonth = YearMonth.from(now.minusMonths(1)); // 从上个月开始
        List<LocalDate> months = new ArrayList<>();  // 存放近一年（从上个月开始）的每个月最后一天
        List<Integer> memberCount = new ArrayList<>();  // 存放总会员数
        for (int i = 0; i < 12; i++) {
            LocalDate date = yearMonth.atEndOfMonth();   // YearMonth.atEndOfMonth获取该月最后一天
            months.add(date);
            yearMonth = yearMonth.minusMonths(1);  // 月份减一
            Integer count = memberMapper.countMemberByDate(date);  // 根据日期查询总会员数
            memberCount.add(count);
        }
        MemberReportVO memberReportVO = new MemberReportVO();
        Collections.reverse(months);   // 反转
        memberReportVO.setMonths(months);
        Collections.reverse(memberCount);  // 反转
        memberReportVO.setMemberCount(memberCount);
        return memberReportVO;
    }


    /**
     * 获取套餐占比统计数据
     * @return
     */
    @Override
    public SetmealReportVO getSetmealReport() {
        List<String> setmealNames = setmealMapper.getSetmealNames();
        List<SetmealCount> setmealCount = setmealMapper.getSetmealCount();
        SetmealReportVO setmealReportVO = new SetmealReportVO();
        setmealReportVO.setSetmealNames(setmealNames);
        setmealReportVO.setSetmealCount(setmealCount);
        return setmealReportVO;
    }

    /**
     * 获取运营统计数据
     * @return
     */
    @Override
    public BusinessReportDataVO getBusinessReportData() {
        BusinessReportDataVO businessReportDataVO = new BusinessReportDataVO();
        LocalDate now = LocalDate.now();  // 今日日期
        Date thisWeekMonday = DateUtils.getThisWeekMonday();  // 获取本周的第一天
        Date firstDay4ThisMonth = DateUtils.getFirstDay4ThisMonth(); // 本月的第一天
        businessReportDataVO.setReportDate(now); // 日期
        businessReportDataVO.setTodayNewMember(memberMapper.findTodayNewMember(now)); // 今日新增会员数
        businessReportDataVO.setTotalMember(memberMapper.countMemberByDate(now));  // 总会员数
        businessReportDataVO.setThisWeekNewMember(memberMapper.findThisWeekNewMember(thisWeekMonday)); // 本周新增会员数
        businessReportDataVO.setThisMonthNewMember(memberMapper.findThisMonthNewMember(firstDay4ThisMonth)); // 本月新增会员数
        businessReportDataVO.setTodayOrderNumber(orderMapper.findTodayOrderNumber(now));  // 今日预约数
        businessReportDataVO.setTodayVisitsNumber(orderMapper.findTodayVisitsNumber(now, Order.ORDERSTATUS_YES)); // 今日到诊数
        businessReportDataVO.setThisWeekOrderNumber(orderMapper.findThisWeekOrderNumber(thisWeekMonday));  // 本周预约数
        businessReportDataVO.setThisWeekVisitsNumber(orderMapper.findThisWeekVisitsNumber(thisWeekMonday, Order.ORDERSTATUS_YES)); // 本周到诊数
        businessReportDataVO.setThisMonthOrderNumber(orderMapper.findThisMonthOrderNumber(firstDay4ThisMonth));  // 本月预约数
        businessReportDataVO.setThisMonthVisitsNumber(orderMapper.findThisMonthVisitsNumber(firstDay4ThisMonth, Order.ORDERSTATUS_YES)); // 本月到诊数
        businessReportDataVO.setHotSetmeal(setmealMapper.findHotSetmeal());  // 热门套餐
        return businessReportDataVO;
    }

    /**
     * 导出运营数据到Excel并提供客户端下载
     */
    @Override
    public void exportBusinessReport(HttpServletResponse response) {
        /*
        this.getClass(): 获取当前类的 Class 对象。
        getClassLoader(): 获取当前类的类加载器。
        getResourceAsStream(filename): 通过类加载器从应用程序的类路径中获取指定文件的输入流。
         */
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("templates/report_template.xlsx");
        // 获取运营统计数据
        BusinessReportDataVO businessReportData = getBusinessReportData();
        try {
            // 1 基于模板文件创建一个新的Excel文件
            XSSFWorkbook excel = new XSSFWorkbook(inputStream);
            // 获取表格文件的sheet页
            XSSFSheet sheet = excel.getSheet("Sheet1");
            // 2 设置数据
            // 获取sheet页的第3行
            XSSFRow row = sheet.getRow(2);
            row.getCell(5).setCellValue(businessReportData.getReportDate().toString());  // 日期
            // 获取sheet的第5行
            row = sheet.getRow(4);
            row.getCell(5).setCellValue(businessReportData.getTodayNewMember()); // 今日新增会员数
            row.getCell(7).setCellValue(businessReportData.getTotalMember());  // 总会员数
            // 获取sheet的第6行
            row = sheet.getRow(5);
            row.getCell(5).setCellValue(businessReportData.getThisWeekNewMember()); // 本周新增会员数
            row.getCell(7).setCellValue(businessReportData.getThisMonthNewMember());  // 本月新增会员数
            // 获取sheet的第8行
            row = sheet.getRow(7);
            row.getCell(5).setCellValue(businessReportData.getTodayOrderNumber()); // 今日预约数
            row.getCell(7).setCellValue(businessReportData.getTodayVisitsNumber());  // 今日到诊数
            // 获取sheet的第9行
            row = sheet.getRow(8);
            row.getCell(5).setCellValue(businessReportData.getThisWeekOrderNumber()); // 本周预约数
            row.getCell(7).setCellValue(businessReportData.getThisWeekVisitsNumber());  // 本周到诊数
            // 获取sheet的第10行
            row = sheet.getRow(9);
            row.getCell(5).setCellValue(businessReportData.getThisMonthOrderNumber()); // 本月预约数
            row.getCell(7).setCellValue(businessReportData.getThisMonthVisitsNumber());  // 本月到诊数
            List<HotSetmeal> hotSetmeal = businessReportData.getHotSetmeal(); // 热门套餐数据
            System.out.println(hotSetmeal.get(0));
            // 获取sheet的第13到16行
            for (int i = 12; i < 16; i++) {
                row = sheet.getRow(i);
                row.getCell(4).setCellValue(hotSetmeal.get(i - 12).getName());  // 套餐名称
                row.getCell(5).setCellValue(hotSetmeal.get(i - 12).getSetmeal_count());  // 预约数量
                row.getCell(6).setCellValue(hotSetmeal.get(i - 12).getProportion()); // 占比
            }

            // 获取ServletOutputStream对象，用于向客户端写入相应数据
            ServletOutputStream servletOutputStream = response.getOutputStream();
            // 设置响应的ContentType为application/octet-stream,这是一种常见的MIME类型，表示任意的二进制流
            response.setContentType("application/vnd.ms-excel");
            // 设置响应头Content-Disposition为attachment，告诉客户端将文件作为附件下载，同时设置了文件名
            response.setHeader("Content-Disposition", "attachment;fileName=report.xlsx");
            // 将Excel工作簿的内容写入到SercvletOutputStream中，从而将文件内容发送给客户端
            excel.write(servletOutputStream);

            // 释放资源
            excel.close();
            servletOutputStream.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
